load("@rules_rust//rust:defs.bzl", "rust_doc_test", "rust_library", "rust_test")
load("//bazel:defs.bzl", "rust_ic_test")

package(default_visibility = ["//visibility:public"])

DEPENDENCIES = [
    # Keep sorted.
    "//packages/ic-ledger-hash-of:ic_ledger_hash_of",
    "//packages/icrc-ledger-types:icrc_ledger_types",
    "//rs/crypto/sha2",
    "//rs/ledger_suite/common/ledger_canister_core",
    "//rs/ledger_suite/common/ledger_core",
    "//rs/types/base_types",
    "@crate_index//:candid",
    "@crate_index//:ciborium",
    "@crate_index//:hex",
    "@crate_index//:num-bigint",
    "@crate_index//:num-traits",
    "@crate_index//:serde",
    "@crate_index//:serde_bytes",
    "@crate_index//:thiserror",
]

MACRO_DEPENDENCIES = [
    # Keep sorted.
    "@crate_index//:async-trait",
]

DEV_DEPENDENCIES = [
    # Keep sorted.
    "//packages/icrc-ledger-types:icrc_ledger_types",
    "//rs/ledger_suite/common/ledger_canister_core",
    "//rs/ledger_suite/common/ledger_core",
    "//rs/ledger_suite/icrc1/test_utils",
    "@crate_index//:candid",
    "@crate_index//:ciborium",
    "@crate_index//:leb128",
    "@crate_index//:proptest",
    "@crate_index//:rand",
]

MACRO_DEV_DEPENDENCIES = [
    # Keep sorted.
    "@crate_index//:proptest-derive",
    "@crate_index//:test-strategy",
]

rust_library(
    name = "icrc1",
    srcs = glob(["src/**/*.rs"]),
    crate_name = "ic_icrc1",
    proc_macro_deps = MACRO_DEPENDENCIES,
    version = "0.9.0",
    deps = DEPENDENCIES,
)

rust_test(
    name = "icrc1_unit_test",
    crate = ":icrc1",
    deps = DEV_DEPENDENCIES,
)

rust_doc_test(
    name = "icrc1_doc_test",
    crate = ":icrc1",
)

rust_test(
    name = "icrc1_test",
    srcs = ["tests/tests.rs"],
    proc_macro_deps = MACRO_DEV_DEPENDENCIES,
    deps = [
        # Keep sorted.
        ":icrc1",
        "//packages/ic-ledger-hash-of:ic_ledger_hash_of",
        "//rs/ledger_suite/icrc1/tokens_u256",
        "//rs/ledger_suite/icrc1/tokens_u64",
        "//rs/types/base_types",
    ] + DEV_DEPENDENCIES,
)

[
    # To run this test,
    #
    #     bazel \
    #         test \
    #         --test_env=SSH_AUTH_SOCK \
    #         --test_timeout=43200 \
    #         //rs/ledger_suite/icrc1:icrc_ledger_suite_integration_golden_state_upgrade_downgrade_test
    #
    # To run the U256 token version of the test (for ckETH and ckERC20 tokens), use:
    #
    #         //rs/ledger_suite/icrc1:icrc_ledger_suite_integration_golden_state_upgrade_downgrade_test_u256
    #
    # The unusual things in this command are:
    #  - `--test_env=SSH_AUTH_SOCK`: This causes the SSH_AUTH_SOCK environment variable to be "forwarded" from
    #    your shell to the sandbox where the test is run. This authorizes the test to download the test data.
    #  - `--test_timeout=43200`: This sets the test timeout to 12 hours (more than currently required).
    #
    # Additionally, the following flags are recommended (but not required):
    #
    # --test_output=streamed
    # --test_arg=--nocapture
    #
    # These let you watch the progress of the test, rather than only being able to see the output only
    # at the end.
    #
    # See the .bazelrc for more configuration information.
    rust_ic_test(
        name = "icrc_ledger_suite_integration_golden_state_upgrade_downgrade_test" + name_suffix,
        # This uses on the order of 50 GB of disk space.
        # Therefore, size = "large" is not large enough.
        size = "enormous",
        srcs = [
            "tests/common.rs",
            "tests/golden_state_upgrade_downgrade.rs",
        ],
        crate_features = features,
        crate_root = "tests/golden_state_upgrade_downgrade.rs",
        data = [
            "//rs/ledger_suite/icrc1/archive:archive_canister" + name_suffix + ".wasm.gz",
            "//rs/ledger_suite/icrc1/index-ng:index_ng_canister" + name_suffix + ".wasm.gz",
            "//rs/ledger_suite/icrc1/ledger:ledger_canister" + name_suffix + ".wasm.gz",
            "@mainnet_canisters//:ck_btc_archive.wasm.gz",
            "@mainnet_canisters//:ck_btc_index.wasm.gz",
            "@mainnet_canisters//:ck_btc_ledger.wasm.gz",
            "@mainnet_canisters//:ck_eth_archive.wasm.gz",
            "@mainnet_canisters//:ck_eth_index.wasm.gz",
            "@mainnet_canisters//:ck_eth_ledger.wasm.gz",
            "@mainnet_canisters//:sns_archive.wasm.gz",
            "@mainnet_canisters//:sns_index.wasm.gz",
            "@mainnet_canisters//:sns_ledger.wasm.gz",
            "@mainnet_canisters//:sns_ledger_v2.wasm.gz",
        ],
        env = {
            "CARGO_MANIFEST_DIR": "rs/ledger_suite/icrc1",
            "CKBTC_IC_ICRC1_ARCHIVE_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:ck_btc_archive.wasm.gz)",
            "CKBTC_IC_ICRC1_INDEX_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:ck_btc_index.wasm.gz)",
            "CKBTC_IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:ck_btc_ledger.wasm.gz)",
            "CKETH_IC_ICRC1_ARCHIVE_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:ck_eth_archive.wasm.gz)",
            "CKETH_IC_ICRC1_INDEX_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:ck_eth_index.wasm.gz)",
            "CKETH_IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:ck_eth_ledger.wasm.gz)",
            "IC_ICRC1_ARCHIVE_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:sns_archive.wasm.gz)",
            "IC_ICRC1_INDEX_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:sns_index.wasm.gz)",
            "IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH": "$(rootpath @mainnet_canisters//:sns_ledger.wasm.gz)",
            "IC_ICRC1_LEDGER_DEPLOYED_VERSION_2_WASM_PATH": "$(rootpath @mainnet_canisters//:sns_ledger_v2.wasm.gz)",
            "IC_ICRC1_ARCHIVE_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/archive:archive_canister" + name_suffix + ".wasm.gz)",
            "IC_ICRC1_INDEX_NG_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/index-ng:index_ng_canister" + name_suffix + ".wasm.gz)",
            "IC_ICRC1_LEDGER_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/ledger:ledger_canister" + name_suffix + ".wasm.gz)",
        },
        tags = [
            "fi_tests_nightly",  # Run this test in the fi-tests-nightly GitHub Action job.
            "no-sandbox",  # such that the test can access the file $SSH_AUTH_SOCK.
            "requires-network",  # Because mainnet state is downloaded (and used).
        ],
        deps = [
            # Keep sorted.
            ":icrc1",
            "//packages/icrc-ledger-types:icrc_ledger_types",
            "//rs/ledger_suite/icrc1/index-ng",
            "//rs/ledger_suite/icrc1/ledger",
            "//rs/ledger_suite/test_utils/in_memory_ledger:ic-ledger-suite-in-memory-ledger" + name_suffix,
            "//rs/ledger_suite/common/ledger_core",
            "//rs/ledger_suite/icrc1/test_utils",
            "//rs/ledger_suite/icrc1/tokens_u256",
            "//rs/ledger_suite/icrc1/tokens_u64",
            "//rs/ledger_suite/test_utils/state_machine_helpers:ic-ledger-suite-state-machine-helpers",
            "//rs/nns/test_utils/golden_nns_state",
            "//rs/rust_canisters/canister_test",
            "//rs/state_machine_tests",
            "//rs/test_utilities/load_wasm",
            "//rs/types/base_types",
            "@crate_index//:candid",
            "@crate_index//:hex",
            "@crate_index//:lazy_static",
            "@crate_index//:num-traits",
        ],
    )
    for (name_suffix, features, extra_deps) in [
        (
            "",
            [],
            ["//rs/ledger_suite/icrc1/tokens_u64"],
        ),
        (
            "_u256",
            ["u256-tokens"],
            ["//rs/ledger_suite/icrc1/tokens_u256"],
        ),
    ]
]

[
    rust_ic_test(
        name = "upgrade_downgrade" + name_suffix,
        srcs = [
            "tests/common.rs",
            "tests/upgrade_downgrade.rs",
        ],
        crate_features = features,
        crate_root = "tests/upgrade_downgrade.rs",
        data = [
            "//rs/ledger_suite/icrc1/index-ng:index_ng_canister" + name_suffix + ".wasm.gz",
            "//rs/ledger_suite/icrc1/ledger:ledger_canister" + name_suffix + ".wasm.gz",
            mainnet_ledger,
            mainnet_index,
        ],
        env = {
            "CARGO_MANIFEST_DIR": "rs/ledger_suite/icrc1",
            "IC_ICRC1_INDEX_NG_DEPLOYED_VERSION_WASM_PATH": "$(rootpath " + mainnet_index + ")",
            "IC_ICRC1_INDEX_NG_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/index-ng:index_ng_canister" + name_suffix + ".wasm.gz)",
            "IC_ICRC1_LEDGER_DEPLOYED_VERSION_WASM_PATH": "$(rootpath " + mainnet_ledger + ")",
            "IC_ICRC1_LEDGER_WASM_PATH": "$(rootpath //rs/ledger_suite/icrc1/ledger:ledger_canister" + name_suffix + ".wasm.gz)",
        },
        deps = [
            # Keep sorted.
            "//packages/ic-ledger-hash-of:ic_ledger_hash_of",
            "//packages/icrc-ledger-types:icrc_ledger_types",
            "//rs/ledger_suite/common/ledger_canister_core",
            "//rs/ledger_suite/common/ledger_core",
            "//rs/ledger_suite/icrc1",
            "//rs/ledger_suite/icrc1/index-ng",
            "//rs/ledger_suite/icrc1/ledger",
            "//rs/ledger_suite/tests/sm-tests/constants:ic-ledger-suite-state-machine-tests-constants",
            "//rs/registry/subnet_type",
            "//rs/state_machine_tests",
            "//rs/test_utilities/load_wasm",
            "//rs/types/base_types",
            "//rs/types/types",
            "@crate_index//:candid",
            "@crate_index//:cddl",
            "@crate_index//:hex",
            "@crate_index//:ic-metrics-encoder",
            "@crate_index//:leb128",
            "@crate_index//:num-traits",
            "@crate_index//:proptest",
            "@crate_index//:serde_bytes",
        ] + extra_deps,
    )
    for (name_suffix, mainnet_ledger, mainnet_index, features, extra_deps) in [
        (
            "",
            "@mainnet_canisters//:ck_btc_ledger.wasm.gz",
            "@mainnet_canisters//:ck_btc_index.wasm.gz",
            [],
            ["//rs/ledger_suite/icrc1/tokens_u64"],
        ),
        (
            "_u256",
            "@mainnet_canisters//:ck_eth_ledger.wasm.gz",
            "@mainnet_canisters//:ck_eth_index.wasm.gz",
            ["u256-tokens"],
            ["//rs/ledger_suite/icrc1/tokens_u256"],
        ),
    ]
]
